home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Stacks / Updates⁄New / TEXAS for BMUG / C progs / brwsr.2 ƒ / do_targets_etc.2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-10-08  |  5.9 KB  |  243 lines  |  [TEXT/KAHL]

  1. /* some functions to respond to various user inputs...
  2.  *  870806-13-... ^z
  3.  */
  4.  
  5. #include <stdio.h>            /* for FILE, printf(), etc. */
  6. #include <strings.h>        /* for strcpy(), etc. */
  7. #include <unix.h>            /* for exit(), etc. */
  8. #include <proto.h>            /* for function prototypes */
  9. #include "brwsr.h"            /* for various definitions */
  10. #include "brwsr.proto.h"    /* for my function prototypes */
  11.  
  12.  
  13. /* function to move down a level in the browser hierarchy:
  14.  *    INDEX --> CONTEXT --> TEXT
  15.  * includes various safety features against errors, and takes
  16.  * care of initializations for the level being entered ... also
  17.  * displays the current line when entering the new level, for the user's
  18.  * convenience....
  19.  *
  20.  * Modified for subset operations, ^z - 870813.  Note that we must check
  21.  * here to be sure that we are descending into a non-empty subset when
  22.  * a subset is active and we are descending from INDEX --> CONTEXT;
  23.  * we also must make sure in that case that we initialize the CONTEXT
  24.  * display to start with the first good item, not just min_item[CONTEXT].
  25.  */
  26.  
  27. void do_descend ()
  28.   {
  29.     extern int level, empty_subset;
  30.     extern long current_item[], min_item[], max_item[], subset_rec_count;
  31.     extern KEY_REC this_rec, prev_rec;
  32.     extern FILE *doc_file;
  33.     extern char *subset;
  34.     
  35.     if (doc_file == NULL)
  36.       {
  37.         beep ();
  38.         printf ("No file open!\n");
  39.         return;
  40.       }
  41.  
  42.     if (current_item[INDEX] < 0)
  43.       {
  44.         beep ();
  45.         printf ("No current index item!\n");
  46.         return;
  47.       }
  48.     
  49.     if (subset != NULL && (empty_subset || subset_rec_count == 0))
  50.       {
  51.         beep ();
  52.         printf ("No items in subset!\n");
  53.         return;
  54.       }
  55.  
  56.     ++level;
  57.  
  58.     if (level == CONTEXT)
  59.       {
  60.         min_item[CONTEXT] = prev_rec.ccount;
  61.         max_item[CONTEXT] = this_rec.ccount - 1;
  62.         if (subset == NULL)
  63.             current_item[CONTEXT] = min_item[CONTEXT];
  64.         else
  65.           {
  66.             current_item[CONTEXT] = min_item[CONTEXT] - 1;
  67.             make_subindex_move (1L);
  68.           }
  69.         current_item[TEXT] = get_ptr_rec (current_item[CONTEXT]);
  70.       }
  71.  
  72.     if (level == TEXT)
  73.         current_item[TEXT] =
  74.                 start_of_line (current_item[TEXT]);
  75.  
  76.     if (level > TEXT)
  77.       {
  78.         beep ();
  79.         printf ("Can't descend past full text display!\n");
  80.         level = TEXT;
  81.       }
  82.  
  83.     show_current_item ();
  84.   }
  85.  
  86. /* function to move up a level in the browser hierarchy:
  87.  *       TEXT --> CONTEXT --> INDEX
  88.  * includes a safety net against going past INDEX, and
  89.  * displays the current line when entering the new level...
  90.  * note that when coming up from TEXT, must reset the current_item[TEXT]
  91.  * before displaying CONTEXT line, as TEXT browsing changes it....
  92.  */
  93.  
  94.  
  95. void do_ascend ()
  96.   {
  97.     extern int level;
  98.     
  99.     --level;
  100.     
  101.     if (level < INDEX)
  102.       {
  103.         beep ();
  104.         printf ("Can't ascend past index display!\n");
  105.         level = INDEX;
  106.       }
  107.  
  108.     if (level == CONTEXT)
  109.         current_item[TEXT] = get_ptr_rec (current_item[CONTEXT]);
  110.  
  111.     show_current_item ();
  112.   }
  113.  
  114.  
  115. /* function to jump the INDEX display to a target entered by the
  116.  * user ... does a simple binary search (see K&R p.54) to get there
  117.  * and then shows that line of the INDEX ... and if the
  118.  * target word is not found, it beeps and shows the preceeding
  119.  * word available in the index ... if called from another level, it
  120.  * jumps to the INDEX level ...
  121.  */
  122.  
  123. void do_target_jump (cmd)
  124.   char cmd[];
  125.   {
  126.     register int c, diff;
  127.     register long low, high, mid;
  128.     KEY_REC target_item, this_item;
  129.     extern long current_item[], max_item[];
  130.     extern FILE *key_file;
  131.     extern int level;
  132.     
  133.     if (key_file == NULL)
  134.       {
  135.         beep ();
  136.         printf ("No file open!\n");
  137.         return;
  138.       }
  139.     
  140.     level = INDEX;
  141.     init_target_item (&target_item, cmd);
  142.     low = min_item[INDEX];
  143.     high = max_item[INDEX];
  144.  
  145.     while (low <= high)
  146.       {
  147.         mid = (low + high) / 2;
  148.         get_key_rec (&this_item, mid);
  149.         diff = zstrcmp (target_item.kkey, this_item.kkey);
  150.         if (diff < 0)
  151.             high = mid - 1;
  152.         else if (diff > 0)
  153.             low = mid + 1;
  154.         else
  155.           break;
  156.       }
  157.  
  158.     current_item[INDEX] = mid;
  159.     if (diff < 0)
  160.         --current_item[INDEX];
  161.     if (current_item[INDEX] < 0)
  162.         current_item[INDEX] = 0;
  163.     if (diff != 0)
  164.         beep ();
  165.     show_current_item ();
  166.   }
  167.  
  168.  
  169.  
  170. /* my function to compare two strings and give a result as to who is
  171.  * alphabetically earlier.  Note that this is almost the same as strncmp()
  172.  * with the fixed value of KEY_LENGTH as the maximum comparison distance,
  173.  * except that I must be sure to mask the characters to make them positive
  174.  * (since we want to be able to handle the non-ASCII funny letters in
  175.  * the Apple character set properly/consistently).  If the masking isn't
  176.  * done, then inconsistent results can occur with those non-ASCII chars!
  177.  */
  178.  
  179. int zstrcmp (s1, s2)
  180.   register char *s1, *s2;
  181.   {
  182.     register int n = KEY_LENGTH;
  183.     
  184.     for (; --n && ((*s1 & 0xFF) == (*s2 & 0xFF)); s1++, s2++)
  185.         if (!*s1) break;
  186.         
  187.     return ((*s1 & 0xFF) - (*s2 & 0xFF));
  188.   }
  189.  
  190.  
  191.  
  192. /* initialize the target KEY_REC kkey string to the value typed in by
  193.  * the user ... convert the user's string to all capital letters, and
  194.  * pad it out to KEY_LENGTH with trailing blanks as needed ... use the
  195.  * toupper() function warily (assume that it may be nonstandard and
  196.  * mess up the value of non-lowercase characters, as it seems to on
  197.  * the VAX and Sun C compilers I've tried -- so check and don't apply
  198.  * toupper() except to lower-case characters!)....
  199.  */
  200.  
  201. void init_target_item (rp, cmd)
  202.   KEY_REC *rp;
  203.   char cmd[];
  204.   {
  205.     register int c, n;
  206.  
  207.     strncpy (rp->kkey, "                                    ", KEY_LENGTH);
  208.     for (n = 0; n < KEY_LENGTH && (c = cmd[n]) != 0; ++n)
  209.         rp->kkey[n] = (islower (c) ? toupper (c) : c);
  210.   }
  211.  
  212.  
  213. /* handle the printing out of N lines due to a ".N" user command ... do
  214.  * the job simply by marching down a step and displaying that line N times
  215.  * ... precisely equivalent to hitting the <return> key N times.
  216.  */
  217.  
  218. void do_multiprint (cmd)
  219.   char cmd[];
  220.   {
  221.     register long i, n;
  222.     extern FILE *doc_file;
  223.     
  224.     if (doc_file == NULL)
  225.       {
  226.         beep ();
  227.         printf ("No file open!\n");
  228.         return;
  229.       }
  230.       
  231.     if (cmd[1] == '\0')
  232.         strcat (cmd, "1");
  233.     n = atol (cmd + 1);
  234.     for (i = 0; i < n; ++i)
  235.       {
  236.         if (! make_move (1L))
  237.             break;
  238.         show_current_item ();
  239.       }
  240.   }
  241.  
  242.  
  243.